<?php


namespace app\api\model;



use app\common\library\aliyunsms\alidayu;
use app\common\library\DLock;
use app\common\library\IDMan;
use app\common\library\StatModel;
use app\common\library\UMaleModel;
use think\Db;
use common;
use ApiOper;
use think\db\Query;

class UserRadingOrderModel
{
    protected $table_name = 'tb_user_ride_order';

    function get_time(){
        #判断当前时间是否在时间段内，如果是，则执行
        $begin_time = strtotime("2020-08-07 00:00:00");
        $curr_time = time();
        if($curr_time > $begin_time){
            return true;
        }
        return false;
    }

    function submit($usrinfo, $bike_info, $user_coordinate, $reserve = false, $bluetooth)
    {
        $city_id = $bike_info['city_id'];

        if ($city_id == '520200') {
            //$now = date('Y-m-d H:i:s');
            // return [X_ERROR, "即日7月29日起对车辆维护上牌，维护期过后即可恢复全天正常使用!期间给您造成不便敬请谅解!"];
        }

//        if ($city_id == '510121') {
//            if ($this->get_time())
//                return [X_ERROR, "多多e行电单车将于8月7日进行系统更新维护,给您带来不便敬请谅解！"];
//        }


        if (empty($bike_info['bluetooth_token'])) {
            $bluetooth = 0;
        }
        // $bluetooth = 1;
        if ($bike_info['is_low_battery']) {
            return [X_ERROR, "车辆电量太低，不宜骑行！"];
        }

        if (empty($usrinfo['name'])) {
            return [ERROR_REALNAME_AUTH_FIRST, " 未实名认证!"];
        }

        if (!empty($usrinfo['blacklisted_expire_time']) && time() < strtotime($usrinfo['blacklisted_expire_time'])) {
            return [X_ERROR, " 很抱歉，您暂时不能骑行，请于{$usrinfo['blacklisted_expire_time']}后重试！"];
        }

        if ($bike_info['bus_state'] != 0) {
            if ($bike_info['bus_state'] == BIKE_BUS_STAT_OPER_REPARK || $bike_info['bus_state'] == BIKE_BUS_STAT_USER_REPARK || $bike_info['bus_state'] == BIKE_BUS_STAT_BATTERY_CHANGE) {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆运维中!"];
            } else {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆使用中!"];
            }
        }

        if ($bike_info['inv_state'] != 0) {
            return [USR_ORDER_ERROR_BIKE_BUSY, "未投放的车辆!"];
        }

        if ($bike_info['health_state'] != 0) {
            return [ERROR_BIKE_IN_FAULT, "车辆故障!"];
        }

        $svca = (new ServiceAreaModel())->is_in($bike_info['city_id'], $bike_info['coordinate']);
        if (empty($svca)) {
            return [ERROR_BIKE_OUT_OF_SERVICE_AREA, "服务区外不能骑行！"];
        }

        //$price_rule = $this->get_price_rule($city_id, $svca['id']);
        if ($usrinfo['balance'] < 0) {
            return [ERROR_PAY_FOR_LAST_ORDER_FIRST, "您的账户余额不足，请充值!"];
        }

        $order_count = $this->get_user_unfinished_order_count($usrinfo['id']);
        if ($order_count > 0) {
            return [X_ERROR, "您有进行中的订单或者未支付的订单!"];
        }

        $ID = IDMan::city_order_id($city_id);
        $order_state = $reserve ? RIDE_ORDER_STATE_RESERVE : RIDE_ORDER_STATE_RIDING;

        $start_time = $reserve ? null : date('Y-m-d H:i:s');

        $bike_idle_time = 0;
        if (!empty($bike_info['park_update_time'])) {
            $bike_idle_time = time() - strtotime($bike_info['park_update_time']);
        }

        $order_info = [
            'id' => $ID,
            'city_id' => $city_id,
            'user_id' => $usrinfo['id'],
            'user_name' => $usrinfo['name'],
            'user_phone' => $usrinfo['phone'],
            'bike_id' => $bike_info['id'],
            'bike_sn' => $bike_info['sn'],
            'imei' => $bike_info['imei'],
            'order_state' => $order_state,
            'start_time' => $start_time,
            'start_park_state' => $bike_info['park_state'],
            'start_coordinate' => $bike_info['coordinate'],
            'start_address' => $bike_info['address'],
            'start_park_id' => $bike_info['park_id'],
            'start_park_name' => $bike_info['park_name'],
            'start_npa_id' => $bike_info['npa_id'],
            'start_npa_name' => $bike_info['npa_name'],
            'start_svca_id' => $bike_info['svca_id'],
            'start_svca_name' => $bike_info['svca_name'],
            'create_time' => date('Y-m-d H:i:s'),
            'channel' => ApiOper::instance()->userinfo()['channel'],
            'track' => [
                [
                    $bike_info['coordinate'][0],
                    $bike_info['coordinate'][1],
                    date('Y-m-d H:i:s'),
                    $bike_info['speed'],
                    $bike_info['course'],
                ],
            ],
            'user_start_coordinate' => $user_coordinate,
            'reserve' => intval($reserve),
            'temp_park_duration' => 0,
            'duration' => 0,
            'is_violational' => 0,
            'violation_fine' => 0,
            'violation_blacklisted' => 0,
            'bike_idle_time' => $bike_idle_time,
            'distance' => 0,
        ];

        $order_info['fee_info'] = $this->calc_amount($order_info);

        if ($reserve) {
            (new BikeMgr())->user_order_reserve($city_id, $bike_info['id'], $order_info);
        } else {
            (new BikeMgr())->user_order_start($city_id, $bike_info['id'], $order_info, $bluetooth);
        }


        Db::table($this->table_name)->insert($order_info);

        (new BikeIdleTimeMap())->add($city_id, $bike_info['coordinate'], $order_info['create_time'], $bike_idle_time);
        if ($usrinfo['order_num'] == 0) {
            (new StatModel())->user_count_incr($city_id);
        }
        (new StatModel())->user_order_incr($city_id,$bike_info['svca_id']);

        if ($city_id == '451100'){
            (new UMaleModel())->bike_postInfo($bike_info,1);
        }

        $phone = $usrinfo['phone'];
        $arr_phone = ['18177485800','18778420135','18070666526'];
        $report_phone = ['15259160229‬','13507842808'];
        if (in_array($phone,$arr_phone)){
            $speed = "0 km/h";
            $city = "多多e行";
            $city_info = CityModel::instance()->query_info($city_id);
            if (!empty($city_info)) {
                $city = $city_info['name'];
            }
            $data = [
                'city' => $city,
                'sn' => $bike_info['sn'],
                'date' => date('m-d H:i'),
                'speed' => $speed,
                'addr' => $bike_info['address'],
            ];
            foreach ($report_phone as $phone_tmp) {
                (new alidayu())->send_sms_alert($phone_tmp, ALEERT_SMS_TPL_BIKE_STOLEN_V2, $data);
            }
            //15259160229‬邱捷芳
            //13507842808黄光龙
        }

        return [0, '', $order_info];
    }

    function reride($city_id, $order_id, $bluetooth)
    {
        $order_info = $this->query_info_by_city_id($city_id, $order_id);
        if (empty($order_info)) {
            return [ERROR_QUERY_INFO, "reserved_bike_start_riding get order info error!"];
        }

        $bike_info = BikeModel::instance()->get_info_by_id($order_info['bike_id']);
        if (empty($bike_info['bluetooth_token'])) {
            $bluetooth = 0;
        }
        if (ApiOper::instance()->userinfo()['channel'] == 'alimpu') {
            $bluetooth = 0;
        }

        if ($order_info['order_state'] != RIDE_ORDER_STATE_RESERVE && $order_info['order_state'] != RIDE_ORDER_STATE_TEMP_PARKING) {
            return [ERROR_STATE_DISMATCH, "not  reserved order!"];
        }

        $bike_info_new = [
            'id' => $order_info['bike_id'],
            'imei' => $order_info['imei'],
        ];

        $ret = (new BikeMgr())->user_order_reride($city_id, $bike_info_new, $order_info, $bluetooth);
        if ($ret[0] != 0) {
            return [ERROR_LOCK_ERROR, "开锁失败，请重试！"];
        }

        $temp_park_duration = time() - strtotime($order_info['temp_park_time']) + $order_info['temp_park_duration'];

        $data = [
            'order_state' => RIDE_ORDER_STATE_RIDING,
            'temp_park_duration' => $temp_park_duration,
        ];
        if (empty($order_info['start_time'])) {
            $data['start_time'] = date('Y-m-d H:i:s');
        }
        $where = [
            'city_id' => $city_id,
            'id' => $order_id,
        ];

        Db::table($this->table_name)->where($where)->update($data);
        //hisql::update('tb_user_ride_order', $data, $where);
    }

    function park_temp($city_id, $order_id, $bluetooth)
    {
        $order_info = $this->query_info_by_city_id($city_id, $order_id);
        if (empty($order_info)) {
            return [ERROR_QUERY_INFO, "订单号不存在!"];
        }

        if ($order_info['order_state'] != RIDE_ORDER_STATE_RIDING) {
            return [ERROR_STATE_DISMATCH, "请重试！"];
        }

        $bike_info = BikeModel::instance()->get_info_by_id($order_info['bike_id']);
        if (empty($bike_info['bluetooth_token'])) {
            $bluetooth = 0;
        }

        $srva = (new ServiceAreaModel())->is_in($city_id, $bike_info['coordinate']);
        if (empty($srva)) {
            return [ERROR_STATE_DISMATCH, "服务区外不能临时锁车！"];
        }

        $ret = (new BikeMgr())->user_order_temp_park($city_id, $bike_info, $order_info, $bluetooth);
        if ($ret[0] != 0) {
            return [ERROR_LOCK_ERROR, "车辆信号不佳，锁车失败！"];
        }

        $data = [
            'order_state' => RIDE_ORDER_STATE_TEMP_PARKING,
            'temp_park_time' => date('Y-m-d H:i:s'),
        ];
        $where = [
            'city_id' => $city_id,
            'id' => $order_id,
        ];
        Db::table($this->table_name)->where($where)->update($data);
    }

    function finish($order_info, $user_coordinate, $flush_reason, $report_bike_fault_types, $bluetooth)
    {
        $city_id = $order_info['city_id'];
        $order_id = $order_info['id'];
        if (empty($order_info)) {
            return [ERROR_QUERY_INFO, "finish order get order info error!"];
        }

        if ($order_info['order_state'] != RIDE_ORDER_STATE_RIDING && $order_info['order_state'] != RIDE_ORDER_STATE_TEMP_PARKING) {
            return [ERROR_STATE_DISMATCH, "订单状态不匹配！"];
        }

        $bound_order_info = [
            'order_type' => ORDER_TYPE_USER_RIDE,
            'order_id' => $order_info['id'],
            'op' => '结束订单',
        ];

        $bike_info = BikeModel::instance()->get_info_by_id($order_info['bike_id']);

        if (empty($bike_info['bluetooth_token'])) {
            $bluetooth = 0;
        }
        if (ApiOper::instance()->userinfo()['channel'] == 'alimpu') {
            $bluetooth = 0;
        }

        if (!$bluetooth) {
            if ($bike_info['is_defend_on'] == 0 || $bike_info['is_acc_on'] == 1 || $bike_info['is_wheel_locked'] == 0) {
                if ($bike_info['last_order_id'] == $order_id) {
                    $ret = (new BikeMgr())->lock($city_id, $order_info['bike_id'], $bound_order_info);
                    if ($ret[0] != 0) {
                        $ret[0] = 0;
                        //throw_myexception(X_ERROR, "车辆信号不佳，锁车失败！");
                    }
                }
            }
        }

        $now = date('Y-m-d H:i:s');
//$track = (new XiaoAnEcuModel())->get_track($bike_info['imei'], $order_info['start_time'], $now);
//if ($track === FALSE) {
// return [ERROR_GET_BIKE_TRACK, "get ecu track rt error!"];
//  }

        $track = $order_info['track'];
        $park_info = [
            'park_state' => BIKE_PARK_STAT_FREE,
            'park_update_time' => date('Y-m-d H:i:s'),
        ];

        $service_area_info = (new ServiceAreaModel())->is_in($city_id, $bike_info['coordinate']);
        if (empty($service_area_info)) {
            $park_info['svca_id'] = null;
            $park_info['svca_name'] = null;
            $park_info['park_state'] = BIKE_PARK_STAT_OSA;
        } else {
            $park_info['svca_id'] = $service_area_info['id'];
            $park_info['svca_name'] = $service_area_info['name'];
        }

        $no_parking_area_info = (new NPAModel())->is_in($city_id, $bike_info['coordinate']);
        if (!empty($no_parking_area_info)) {
            $park_info['park_state'] = BIKE_PARK_STAT_NPA;
            $park_info['npa_id'] = $no_parking_area_info['id'];
            $park_info['npa_name'] = $no_parking_area_info['name'];
        } else {
            $park_info['npa_id'] = null;
            $park_info['npa_name'] = null;
        }

        $park = (new ParkModel())->is_in($city_id, $bike_info['coordinate']);

        if (!empty($park)) {
            $park_info['park_state'] = BIKE_PARK_STAT_PARK;
            $park_info['park_id'] = $park['id'];
            $park_info['park_name'] = $park['name'];
        } else {
            $park_info['park_id'] = null;
            $park_info['park_name'] = null;
        }

        if (ApiOper::instance()->userinfo()['user_type'] == OPER_TYPE_USER){
            if ($park_info['npa_id'] != null && $no_parking_area_info['is_no_park'] == 1) {
                return [ERROR_QUERY_INFO, "该区域是禁行区，不能停车!"];
            }
        }

        $track[] = [
            $bike_info['coordinate'][0],
            $bike_info['coordinate'][1],
            date('Y-m-d H:i:s'),
            $bike_info['speed'],
            $bike_info['course'],
        ];

        /*
          $this->append_track($city_id, $order_id, [
          $bike_info['coordinate'][0],
          $bike_info['coordinate'][1],
          date('Y-m-d H:i:s'),
          $bike_info['speed'],
          $bike_info['course'],
          ]); */

        $duration = time() - strtotime($order_info['start_time']);

        $data = [
            'order_state' => RIDE_ORDER_STATE_FINISH,
            'end_time' => $now,
            'end_coordinate' => $bike_info['coordinate'],
            'end_address' => $bike_info['address'],
            'track' => $track,
            'duration' => $duration,
            'end_park_state' => $park_info['park_state'],
            'end_park_id' => $park_info['park_id'],
            'end_park_name' => $park_info['park_name'],
            'end_npa_id' => $park_info['npa_id'],
            'end_npa_name' => $park_info['npa_name'],
            'end_svca_id' => $park_info['svca_id'],
            'end_svca_name' => $park_info['npa_name'],
            'user_end_coordinate' => $user_coordinate,
            'flush_reason' => $flush_reason,
            'report_bike_fault_types' => $report_bike_fault_types,
            'is_pay' => 0,
            //'is_violational' => $is_voilational,
        ];

        if ($order_info['order_state'] == RIDE_ORDER_STATE_TEMP_PARKING) {
            $temp_park_duration = time() - strtotime($order_info['temp_park_time']) + $order_info['temp_park_duration'];
            $data['temp_park_duration'] = $temp_park_duration;
        }

        $fee_info = $this->calc_amount(array_merge($order_info, $data));

        $user_data = (new UserModel())->query_info($order_info['user_id']);

        if ($user_data){
            if (!empty($user_data['use_free_endtime']) && time() < strtotime($user_data['use_free_endtime'])) {
                $fee_info['basic_fee'] = 0;
                $fee_info['vip_basic_fee'] = 0;
                $fee_info['npa_fee'] = 0;
                $fee_info['osvc_fee'] = 0;
                $fee_info['coupon_fee'] = 0;
                $fee_info['no_coupon_fee'] = 0;
                $fee_info['score_need'] = 0;
                $fee_info['total'] = 0;
            }

            //看看是不是数据
            if ($fee_info['is_flush'] == 0 && $fee_info['no_coupon_fee'] > 0 && $data['is_pay'] == 0){
                if (!empty($user_data['ridecard_expire_time']) && time() < strtotime($user_data['ridecard_expire_time'])&& $user_data['ridecard_count']>0 ) {
                    //还在有效期内
                    $ridecard_id = (new UserRideCardOrderModel())->perform($order_info['user_id'],$city_id);
                    if (!empty($ridecard_id)){
                        $fee_info['ridecard_fee'] = 0;//$fee_info['no_coupon_fee'] - $fee_info['mile_fee'] - $fee_info['duration_fee'];
                        $fee_info['ridecard_id'] = $ridecard_id;
                        $fee_info['basic_fee'] = 0;
                        $fee_info['vip_basic_fee'] = 0;
                        $fee_info['mile_fee'] = 0;
                        $fee_info['score_need'] = 0;
//                        if ($fee_info['duration'] > 1800) {
//                            $fee_info['duration_fee'] = ceil($fee_info['duration'] / 30 - 30) * 10;
//                        }
//                        else{
//                            $fee_info['duration_fee'] = 0;
//                        }

                        $fee_info['total'] = $fee_info['duration_fee'] + $fee_info['mile_fee'];
                        $fee_info['no_coupon_fee'] = $fee_info['total'];
                        $fee_info['total'] += $fee_info['npa_fee'];
                        $fee_info['total'] += $fee_info['osvc_fee'];
                    }
                }
            }

            //优惠
            if ($fee_info['is_flush'] == 0 && $fee_info['no_coupon_fee'] > 0 && $fee_info['total'] > 0){
                $coupon_info = $this->calc_coupon($order_info['user_id']);
                if ($coupon_info['coupon_fee'] > 0 && $fee_info['no_coupon_fee'] < $coupon_info['coupon_fee']) {
                    $coupon_info['coupon_fee'] = $fee_info['no_coupon_fee'];
                }

                if ($user_data['balance'] >=0){
                    if ($fee_info['total'] - $coupon_info['coupon_fee']  <= $user_data['balance']) {
                        $fee_info['total'] -= $coupon_info['coupon_fee'];

                        $fee_info['coupon_id'] = $coupon_info['coupon_id'];
                        $fee_info['coupon_metadata'] = $coupon_info['coupon_metadata'];
                        $fee_info['coupon_fee'] = $coupon_info['coupon_fee'];

                        $data['is_pay'] = 1;

                        $fee_info['balance_fee'] = $fee_info['total'];
                        if($fee_info['total'] >0)
                            (new UserModel())->incr_balance($order_info['user_id'], 0 - $fee_info['total']);
                    }
                    else{
                        $data['is_pay'] = 0;
                    }
                }
                else{
                    $data['is_pay'] = 0;
                }

            }
        }


        $data = array_merge($data, [
            'original_amount' => $fee_info['total'],
            'coupon_id' => $fee_info['coupon_id'],
            'coupon_metadata' => $fee_info['coupon_metadata'],
            'distance' => $fee_info['distance'],
            'is_flush' => $fee_info['is_flush'],
            'paid_amount' => $fee_info['total'],
            'fee_info' => $fee_info,
            'violation_fine' => $fee_info['npa_fee'] + $fee_info['osvc_fee'],
            'ridecard_id' => $fee_info['ridecard_id']
        ]);

        if ($data['paid_amount'] ==0){
            $data['is_pay'] = 1;
        }

        $where = [
            'city_id' => $city_id,
            'id' => $order_id,
        ];


        Db::table($this->table_name)->where($where)->update($data);

        if($data['paid_amount']>0){
            (new StatModel())->user_ride_order_amount_incr($order_info['city_id'], $order_info['create_time'], $data['paid_amount'],$order_info['start_svca_id']);
        }

        if($data['is_pay'] == 1){
            //支付完成
            (new PayModel())->add_record($city_id, $order_info['user_id'], ORDER_TYPE_USER_RIDE, $order_id, PAY_GATEWAY_WALLET, $fee_info['total']);
        }
        else{

        }

        if ($fee_info['npa_fee'] > 0 || $fee_info['osvc_fee'] > 0) {
            (new UserModel())->incr_violation_count($order_info['user_id']);
        }

        if ($data['coupon_id'] && $data['is_pay'] == 1) {
            (new CouponModel())->perform($data['coupon_id'],$order_id);
        }

        (new BikeMgr())->user_order_finish($city_id, $bike_info['id'], $park_info,$fee_info['distance'],$fee_info['is_flush']);
        (new BikeMgr())->asyn_grasproad_track($city_id, $order_id);

        if ($bluetooth) {
            if ($bike_info['is_defend_on'] == 0 || $bike_info['is_acc_on'] == 1 || $bike_info['is_wheel_locked'] == 0) {
                if ($bike_info['last_order_id'] == $order_id) {
                    //TODO
                    (new BikeMgr())->asyn_lock($city_id, $order_info['bike_id'], $bound_order_info, 0);
                    (new BikeMgr())->asyn_check_defend_state($bike_info['id']);
                }
            }
        }

        (new BikeMgr())->asyn_update_bluetooth($bike_info);

//        if ($city_id){
//            //从2019 12.14 00:00:00 -- 2020.1.31
//            $begin_time = "2020-05-01 00:00:00";
//            $end_time = "2020-05-05 23:59:59";
//            if((strtotime($now) - strtotime($begin_time) >=0)&&(strtotime($now) - strtotime($end_time) <=0)){
//                if($fee_info['is_flush'] == 0 && $data['is_pay'] == 1)
//                {
//                    $may_amount = common::get_may_amount();
//                    (new CouponModel())->create_coupon_May_Day($may_amount,$order_info['user_id'],'五一感恩前行');
//                    $data['may_amount'] =$may_amount;
//                }
//
//            }
//        }

        //更新记录
        $com_info =[
            'bike_sn' => $bike_info['sn'],
            'com_staff_type' => OPER_TYPE_USER,
            'com_staff_id'   => $order_info['user_id'],
            'com_staff_name'   => $order_info['user_name'],
        ];

        (new BikeMgr())->asyn_warn_info($com_info);

        if ($city_id == '451100'){
            (new UMaleModel())->bike_postInfo($bike_info,0);
        }

        $order_info = array_merge($order_info, $data);

        (new StatNewModel())->user_rider_incr($order_info);

        return [0, '', $order_info];
    }

    function force_finish($order_info)
    {
        $city_id = $order_info['city_id'];
        $order_id = $order_info['id'];
        if ($order_info['order_state'] != RIDE_ORDER_STATE_RIDING && $order_info['order_state'] != RIDE_ORDER_STATE_TEMP_PARKING) {
            return [ERROR_STATE_DISMATCH, "订单状态不匹配！"];
        }

        $bound_order_info = [
            'order_type' => ORDER_TYPE_USER_RIDE,
            'order_id' => $order_info['id'],
            'op' => '强制结束订单',
        ];
        $bike_info = BikeModel::instance()->get_info_by_id($order_info['bike_id']);
        if ($bike_info['is_defend_on'] == 0 || $bike_info['is_acc_on'] == 1 || $bike_info['is_wheel_locked'] == 0) {
            $ret = (new BikeMgr())->lock($city_id, $order_info['bike_id'], $bound_order_info);
            if ($ret[0] != 0) {
                // (new BikeMgr())->asyn_acc_off($city_id, $order_info['bike_id'], $bound_order_info);
            }
        }

        if ($order_info['order_state'] < RIDE_ORDER_STATE_FINISH) {

        }
        $now = date('Y-m-d H:i:s');

        $track = $order_info['track'];
        $park_info = [
            'park_state' => BIKE_PARK_STAT_FREE,
            'park_update_time' => $now,
        ];

        $service_area_info = (new ServiceAreaModel())->is_in($city_id, $bike_info['coordinate']);
        if (empty($service_area_info)) {
            $park_info['svca_id'] = null;
            $park_info['svca_name'] = null;
            $park_info['park_state'] = BIKE_PARK_STAT_OSA;
        } else {
            $park_info['svca_id'] = $service_area_info['id'];
            $park_info['svca_name'] = $service_area_info['name'];
        }

        $no_parking_area_info = (new NPAModel())->is_in($city_id, $bike_info['coordinate']);
        if (!empty($no_parking_area_info)) {
            $park_info['park_state'] = BIKE_PARK_STAT_NPA;
            $park_info['npa_id'] = $no_parking_area_info['id'];
            $park_info['npa_name'] = $no_parking_area_info['name'];
        } else {
            $park_info['npa_id'] = null;
            $park_info['npa_name'] = null;
        }

        $park = (new ParkModel())->is_in($city_id, $bike_info['coordinate']);

        if (!empty($park)) {
            $park_info['park_state'] = BIKE_PARK_STAT_PARK;
            $park_info['park_id'] = $park['id'];
            $park_info['park_name'] = $park['name'];
        } else {
            $park_info['park_id'] = null;
            $park_info['park_name'] = null;
        }

        $track[] = [
            $bike_info['coordinate'][0],
            $bike_info['coordinate'][1],
            date('Y-m-d H:i:s'),
            $bike_info['speed'],
            $bike_info['course'],
        ];
        /*
          $this->append_track($city_id, $order_id, [
          $bike_info['coordinate'][0],
          $bike_info['coordinate'][1],
          date('Y-m-d H:i:s'),
          $bike_info['speed'],
          $bike_info['course'],
          ]);
         */
        $duration = time() - strtotime($order_info['start_time']);

        $data = [
            'order_state' => RIDE_ORDER_STATE_FINISH,
            'end_time' => $now,
            'end_coordinate' => $bike_info['coordinate'],
            'end_address' => $bike_info['address'],
            'track' => $track,
            'duration' => $duration,
            'end_park_state' => $park_info['park_state'],
            'end_park_id' => $park_info['park_id'],
            'end_park_name' => $park_info['park_name'],
            'end_npa_id' => $park_info['npa_id'],
            'end_npa_name' => $park_info['npa_name'],
            'end_svca_id' => $park_info['svca_id'],
            'end_svca_name' => $park_info['npa_name'],
            'user_end_coordinate' => null,
            'flush_reason' => null,
            'report_bike_fault_types' => null,
            'is_pay' => 0,
        ];

        $fee_info = $this->calc_amount(array_merge($order_info, $data));


        $user_data = (new UserModel())->query_info($order_info['user_id']);

        if ($user_data){
            if (!empty($user_data['use_free_endtime']) && time() < strtotime($user_data['use_free_endtime'])) {
                $fee_info['basic_fee'] = 0;
                $fee_info['vip_basic_fee'] = 0;
                $fee_info['npa_fee'] = 0;
                $fee_info['osvc_fee'] = 0;
                $fee_info['coupon_fee'] = 0;
                $fee_info['no_coupon_fee'] = 0;
                $fee_info['score_need'] = 0;
                $fee_info['total'] = 0;
            }

            //看看是不是数据
            if ($fee_info['is_flush'] == 0 && $fee_info['no_coupon_fee'] > 0 && $data['is_pay'] == 0){
                if (!empty($user_data['ridecard_expire_time']) && time() < strtotime($user_data['ridecard_expire_time']) && $user_data['ridecard_count']>0) {
                    //还在有效期内
                    $ridecard_id = (new UserRideCardOrderModel())->perform($order_info['user_id'],$city_id);
                    if (!empty($ridecard_id)){
                        $fee_info['ridecard_fee'] = 0;//$fee_info['no_coupon_fee']- $fee_info['mile_fee'] - $fee_info['duration_fee'];
                        $fee_info['ridecard_id'] = $ridecard_id;

                        $fee_info['basic_fee'] = 0;
                        $fee_info['vip_basic_fee'] = 0;
                        $fee_info['mile_fee'] = 0;
                        $fee_info['score_need'] = 0;
//                        if ($fee_info['duration'] > 1800) {
//                            $fee_info['duration_fee'] = ceil($fee_info['duration'] / 30 - 30) * 10;
//                        }
//                        else{
//                            $fee_info['duration_fee'] = 0;
//                        }

                        $fee_info['total'] = $fee_info['duration_fee'] + $fee_info['mile_fee'];
                        $fee_info['no_coupon_fee'] = $fee_info['total'];
                        $fee_info['total'] += $fee_info['npa_fee'];
                        $fee_info['total'] += $fee_info['osvc_fee'];
                    }
                }
            }

            //优惠
            if ($fee_info['is_flush'] == 0 && $fee_info['no_coupon_fee'] > 0  && $fee_info['total'] > 0){
                $coupon_info = $this->calc_coupon($order_info['user_id']);
                if ($coupon_info['coupon_fee'] > 0 && $fee_info['no_coupon_fee'] < $coupon_info['coupon_fee']) {
                    $coupon_info['coupon_fee'] = $fee_info['no_coupon_fee'];
                }

                if ($user_data['balance'] >=0){
                    if ($fee_info['total'] - $coupon_info['coupon_fee']  <= $user_data['balance']) {
                        $fee_info['total'] -= $coupon_info['coupon_fee'];

                        $fee_info['coupon_id'] = $coupon_info['coupon_id'];
                        $fee_info['coupon_metadata'] = $coupon_info['coupon_metadata'];
                        $fee_info['coupon_fee'] = $coupon_info['coupon_fee'];

                        $data['is_pay'] = 1;
                        $fee_info['balance_fee'] = $fee_info['total'];
                        if($fee_info['total'] >0)
                            (new UserModel())->incr_balance($order_info['user_id'], 0 - $fee_info['total']);
                    }
                    else{
                        $data['is_pay'] = 0;
                    }
                }
                else{
                    $data['is_pay'] = 0;
                }

            }
        }


        $data = array_merge($data, [
            'original_amount' => $fee_info['total'],
            'coupon_id' => $fee_info['coupon_id'],
            'coupon_metadata' => $fee_info['coupon_metadata'],
            'distance' => $fee_info['distance'],
            'is_flush' => $fee_info['is_flush'],
            'paid_amount' => $fee_info['total'],
            'fee_info' => $fee_info,
            'violation_fine' => $fee_info['npa_fee'] + $fee_info['osvc_fee'],
            'ridecard_id' => $fee_info['ridecard_id']
        ]);

        if ($data['paid_amount'] ==0){
            $data['is_pay'] = 1;
        }

        $where = [
            'city_id' => $city_id,
            'id' => $order_id,
        ];


        Db::table($this->table_name)->where($where)->update($data);

        if ($order_info['order_state'] == RIDE_ORDER_STATE_TEMP_PARKING) {
            $temp_park_duration = time() - strtotime($order_info['temp_park_time']) + $order_info['temp_park_duration'];
            $data['temp_park_duration'] = $temp_park_duration;
        }

        if ($data['paid_amount'] > 0) {
//            (new UserModel())->incr_balance($order_info['user_id'], 0 - $data['paid_amount']);
            (new StatModel())->user_ride_order_amount_incr($order_info['city_id'], $order_info['create_time'], $data['paid_amount'],$order_info['start_svca_id']);
        }
        if($data['is_pay'] == 1){
            (new PayModel())->add_record($city_id, $order_info['user_id'], ORDER_TYPE_USER_RIDE, $order_id, PAY_GATEWAY_WALLET, $fee_info['total']);
        }

        if ($fee_info['npa_fee'] > 0 || $fee_info['osvc_fee'] > 0) {
            (new UserModel())->incr_violation_count($order_info['user_id']);
        }
        if ($data['coupon_id'] && $data['is_pay'] == 1) {
            (new CouponModel())->perform($data['coupon_id'],$order_id);
        }

        (new BikeMgr())->asyn_grasproad_track($city_id, $order_id);
        (new BikeMgr())->user_order_finish($city_id, $bike_info['id'], $park_info,$fee_info['distance'],$fee_info['is_flush']);

//        if ($city_id){
//            //从2019 12.14 00:00:00 -- 2020.1.31
//            $begin_time = "2020-05-01 00:00:00";
//            $end_time = "2020-05-05 23:59:59";
//            if((strtotime($now) - strtotime($begin_time) >=0)&&(strtotime($now) - strtotime($end_time) <=0)){
//                if($fee_info['is_flush'] == 0 && $data['is_pay'] == 1)
//                {
//                    $may_amount = common::get_may_amount();
//                    (new CouponModel())->create_coupon_May_Day($may_amount,$order_info['user_id'],'五一感恩前行');
//                    $data['may_amount'] =$may_amount;
//                }
//
//            }
//        }

        //更新记录
        $com_info =[
            'bike_sn' => $bike_info['sn'],
            'com_staff_type' => OPER_TYPE_USER,
            'com_staff_id'   => $order_info['user_id'],
            'com_staff_name'   => $order_info['user_name'],
        ];

        (new BikeMgr())->asyn_warn_info($com_info);

        if ($city_id == '451100'){
            (new UMaleModel())->bike_postInfo($bike_info,0);
        }

        $order_info = array_merge($order_info, $data);

        (new StatNewModel())->user_rider_incr($order_info);

        return [0, '', $order_info];
    }

    function get_user_unfinished_order_count($usr_id)
    {
//        $st = "select count(1) as total from tb_user_ride_order where user_id = ? and (is_pay =0 or order_state < " . RIDE_ORDER_STATE_FINISH . ")";
//        $beans = [
//            $usr_id,
//        ];
//
//        $result = hisql::db()->query($st, $beans);
//        $rows = $result->fetchAll(Phalcon\Db::FETCH_ASSOC);
//        return intval($rows[0]['total']);

        $query = new Query();
        $query->whereOr(['is_pay'=>0,'order_state'=>['<',RIDE_ORDER_STATE_FINISH]]);
        return Db::table($this->table_name)->where('user_id','=',$usr_id)->where($query)->count('id');
    }

    function get_user_unfinished_order($usr_id)
    {
        return Db::table($this->table_name)->where('user_id','=',$usr_id)->where('order_state','<',RIDE_ORDER_STATE_FINISH)->count('id');
    }

    function on_act_happy_weekend($order_info)
    {

        $w = date('w', strtotime($order_info['start_time']));
        if ($w != 0 && $w != 6) {
            $w = date('w');
        }
        if ($w != 0 && $w != 6) {
            return;
        }

        if ($order_info['is_flush'] == 0) {
            //(new CouponModel())->create_coupon_type_2($order_info['user_id'], "优惠券");
        }
    }

    function query_info_by_city_id($city_id, $order_id, $query_track = false,$query_fee_info= false)
    {
        $selectlist = [
            'id' => 'string',
            'city_id' => 'string',
            'user_id' => 'string',
            'user_name' => 'string',
            'user_phone' => 'string',
            'bike_id' => 'string',
            'bike_sn' => 'string',
            'imei' => 'string',
            'order_state' => 'int',
            'start_time' => 'string',
            'start_coordinate' => 'array',
            'start_address' => 'string',
            'start_park_id' => 'string',
            'start_park_name' => 'string',
            'start_npa_id' => 'string',
            'start_svca_id' => 'string',
            'end_time' => 'string',
            'end_coordinate' => 'array',
            'end_address' => 'string',
            'end_park_id' => 'string',
            'end_park_name' => 'string',
            //'track' => 'array',
// 'payment_info' => 'array',
            'payment_gateaway' => 'string',
            'distance' => 'int',
            'duration' => 'int',
            'original_amount' => 'int',
            'adjusted_amount' => 'int',
            'paid_amount' => 'int',
            'is_flush' => 'int',
            'create_time' => 'string',
            'channel' => 'string',
            'temp_park_duration' => 'int',
            'temp_park_time' => 'string',
            'is_violational' => 'int',
            'violation_fine' => 'int',
            'violation_blacklisted' => 'int',
            'is_pay' => 'int',
            'user_repark_order' =>  'string',
            'user_repark_order_state' => 'int',
        ];

        if ($query_track) {
            $selectlist['track'] = 'array';
        }

        if ($query_fee_info) {
            $selectlist['fee_info'] = 'object';
        }

        $sfs = common::array_keys($selectlist);
        $beans = [
        ];

        if ($city_id !== null) {
            $beans['city_id'] = $city_id;
        }
        $beans['id'] = $order_id;

        return Db::table($this->table_name)->where($beans)->field($sfs)->find();
    }

    function query_info_with_adjust_amount_record($city_id, $order_id)
    {
        $selectlist = [
            'id' => 'string',
            'city_id' => 'string',
            'user_id' => 'string',
            'user_name' => 'string',
            'user_phone' => 'string',
            'bike_id' => 'string',
            'bike_sn' => 'string',
            'imei' => 'string',
            'order_state' => 'int',
            'start_time' => 'string',
            'start_coordinate' => 'array',
            'start_address' => 'string',
            'start_park_id' => 'string',
            'start_park_name' => 'string',
            'start_npa_id' => 'string',
            'start_npa_name' => 'string',
            'start_svca_id' => 'string',
            'start_svca_name' => 'string',
            'start_park_state' => 'int',
            'end_park_state' => 'int',
            'end_time' => 'string',
            'end_coordinate' => 'array',
            'end_address' => 'string',
            'end_park_id' => 'string',
            'end_park_name' => 'string',
            'end_npa_id' => 'string',
            'end_npa_name' => 'string',
            'end_svca_id' => 'string',
            'end_svca_name' => 'string',
            'track' => 'array',
            'track_grasproad' => 'array',
            // 'payment_info' => 'array',
            'payment_gateaway' => 'string',
            'distance' => 'int',
            'duration' => 'int',
            'original_amount' => 'int',
            'adjusted_amount' => 'int',
            'paid_amount' => 'int',
            'is_flush' => 'int',
            'create_time' => 'string',
            'channel' => 'string',
            'user_start_coordinate' => 'array',
            'user_end_coordinate' => 'array',
            'fee_info' => 'object',
            'temp_park_duration' => 'int',
            'temp_park_time' => 'string',
            'reserve' => 'int',
            'is_violational' => 'int',
            'violation_fine' => 'int',
            'violation_blacklisted' => 'int',
            'is_pay' => 'int',
            'user_repark_order' =>  'string',
            'user_repark_order_state' => 'int',
        ];


        $sfs = common::array_keys($selectlist);
        $beans = [
        ];
        if (isset($city_id)) {
            $beans['city_id'] = $city_id;
        }
        $beans['id'] = $order_id;


        $info = Db::table($this->table_name)->where($beans)->field($sfs)->find();
        if ($info==null)
            return null;

        if ($info['order_state'] >= RIDE_ORDER_STATE_ARRIVE && $info['adjusted_amount'] !== null) {
            $info['adjust_amount_records'] = (new UserRideOrderAdjustAmountModel())->query_list($info['city_id'], $info['id']);
        }
        return $info;
    }

    function query_fee_info($city_id,$order_id)
    {
        $selectlist = [
            'id'=>'string',
            'user_id'=>'string',
            'city_id'=>'string',
            'start_svca_id' => 'string',
            'create_time' => 'string',
            'order_state' => 'int',
            'fee_info' => 'object',
            'is_pay' => 'int',
        ];


        $sfs =  common::array_keys($selectlist);
        $beans = [
        ];
        if (isset($city_id)) {
            $beans['city_id'] = $city_id;
        }
        $beans['id'] = $order_id;


        $info = Db::table($this->table_name)->where($beans)->field($sfs)->find();

        return $info;
    }

    //暂时去除优惠券
    function calc_amount($order_info)
    {
        $city_id = $order_info['city_id'];
        $user_id = $order_info['user_id'];
        $duration = $order_info['duration'];
        $track = $order_info['track'];
        $miles = 0;
        if (!empty($track)) {
            for ($i = 1; $i < count($track); $i++) {
                $A = $track[$i - 1];
                $B = $track[$i];
                $bt = strtotime($B[2]);
                $at = strtotime($A[2]);
                if ($bt <= $at)
                    continue;


                $c1 = [$A[0], $A[1]];
                $c2 = [$B[0], $B[1]];
                $m = common::distance($c1, $c2);
                $d = $bt - $at;
                if ($m / $d > 20) {//时速超过 20* 3.6 72
                    continue;
                }
                $miles += $m;
            }
        }

        $rule_svca_id = isset($order_info['end_svca_id']) ? $order_info['end_svca_id'] : $order_info['start_svca_id'];
        $price_rule = $this->get_price_rule($city_id, $rule_svca_id);

        $basic_fee = 300;
        $basic_kms = 4;
        $basic_mins = 30;
        $fee_min = 1;
        $fee_per_min = 10;
        $fee_per_km = 50;
        $vip_basic_fee = 200;
        //积分
        $use_score = 0;
        $score_basic_fee = 0;     //100分抵1块钱
        $score_fee_percent = 0;    //抵用10%

        if (!empty($price_rule)) {
            if (isset($price_rule['basic_fee'])) {
                $basic_fee = $price_rule['basic_fee'];
            }
            if (isset($price_rule['basic_kms'])) {
                $basic_kms = $price_rule['basic_kms'];
            }
            if (isset($price_rule['basic_mins'])) {
                $basic_mins = $price_rule['basic_mins'];
            }
            if (isset($price_rule['fee_per_min'])) {
                $fee_per_min = $price_rule['fee_per_min'];
            }
            if (isset($price_rule['fee_min'])) {
                $fee_min = intval($price_rule['fee_min']);
            }

            if (isset($price_rule['fee_per_km'])) {
                $fee_per_km = $price_rule['fee_per_km'];
            }

            if (isset($price_rule['vip_basic_fee'])) {
                $vip_basic_fee = $price_rule['vip_basic_fee'];
            }

            if (isset($price_rule['use_score'])){
                $use_score = $price_rule['use_score'];
            }

            if (isset($price_rule['score_fee_per'])){
                $score_fee_percent = $price_rule['score_fee_per'];
            }

            if (isset($price_rule['score_basic_fee'])){
                $score_basic_fee = $price_rule['score_basic_fee'];
            }

        }
        $miles = floor($miles);
        $fee_info = [
            'basic_fee' => $basic_fee,
            'vip_basic_fee' =>$vip_basic_fee,
            'mile_fee' => 0,
            'duration_fee' => 0,
            'duration' => $duration,
            'distance' => $miles,
            'is_flush' => 0,
            'npa_fee' => 0,
            'osvc_fee' => 0,
            'coupon_fee' => 0,
            'coupon_id' => null,
            'coupon_metadata' => null,
            'remark' => null,
            'impunitas' => 1,
            'parkremark'=>null,
            'ridecard_id' => null,
            'pay_fee' => 0,
            'balance_fee' => 0,
            'ridecard_fee' => 0,
            'score_fee' => $score_basic_fee,
            'score_need' => 0,  //需要多少积分
        ];

        if ($miles < 100 && $fee_info['duration'] < 300) {
            $fee_info['is_flush'] = 1;
            $fee_info['basic_fee'] = 0;
            $fee_info['vip_basic_fee'] = 0;
        } else {

            $bike_info = BikeModel::instance()->get_info_by_id($order_info['bike_id']);
            if (empty($bike_info['gps_update_time']) || $bike_info['gps_update_time'] > $order_info['create_time']) {
                if (empty($order_info['end_svca_id'])) {
                    $fee_info['osvc_fee'] = $price_rule['osvc_fee'];
                } else {
                    if ($price_rule['park_mode'] == USER_ORDER_PARK_MODEL_FREE) {
                        if (!empty($order_info['end_npa_id'])) {
                            $fee_info['npa_fee'] = $price_rule['npa_fee'];
                        }
                    } else if ($price_rule['park_model'] == USER_ORDER_PARK_MODEL_PARK) {
                        if (!empty($order_info['end_park_id'])) {
                            $fee_info['npa_fee'] = $price_rule['npa_fee'];
                            $fee_info['parkremark'] = '该区域属于站点停车，需要把车停在指定的黄色区域,否则将产生一定的挪车费用。';
                        }
                    }
                }
            }


            if ($miles > $basic_kms * 1000) {
                $fee_info['mile_fee'] = (ceil($miles / 1000) - $basic_kms) * $fee_per_km;
            }
            if ($fee_info['duration'] > $basic_mins * 60) {
                if ($fee_min >1){
                    $fee_info['duration_fee'] = ceil(ceil($fee_info['duration'] / 60 - $basic_mins)/$fee_min) * $fee_per_min;
                }
                else{
                    $fee_info['duration_fee'] = ceil($fee_info['duration'] / 60 - $basic_mins) * $fee_per_min;
                }

            }
        }

        //      $fee_info['basic_fee'] = 200;
// $fee_info['is_flush'] = 1;

        $basic_fee_data = $fee_info['basic_fee'];
        if ($user_id && $fee_info['is_flush'] == 0) {
            $userinfo = (new UserModel())->query_info($user_id);
            if (!empty($userinfo)) {
                if (isset($userinfo['deposit']) && isset($userinfo['membership_expire_time'])) {
                    if ($userinfo['deposit'] != 0 || !empty($userinfo['membership_expire_time'])) {
                        $basic_fee_data = $fee_info['vip_basic_fee'];
                    }
                }
            }
        }


        $fee_info['total'] = $basic_fee_data + $fee_info['mile_fee'] + $fee_info['duration_fee'];
        if ($fee_info['npa_fee'] + $fee_info['osvc_fee'] > 0) {
            if ($fee_info['osvc_fee'] > 0) {
                $fee_yuan = round($fee_info['osvc_fee'] / 100, 2);
                $fee_info['remark'] = "当前位置在服务区外，结束订单将收取调度费{$fee_yuan}元";
            } else {
                $fee_yuan = round($fee_info['npa_fee'] / 100, 2);
                $fee_info['remark'] = "当前位置在禁停区内，结束订单将收取调度费{$fee_yuan}元";
            }
        }

        $fee_info['no_coupon_fee'] = $fee_info['total'];
        $fee_info['total'] += $fee_info['npa_fee'];
        $fee_info['total'] += $fee_info['osvc_fee'];

        if($fee_info['total'] >0 && $use_score != 0 && $score_fee_percent > 0) {
            $score_fee = ceil($fee_info['total'] * $score_fee_percent) * 100;
            $fee_info['score_need'] = $score_fee *$score_basic_fee;
        }

        return $fee_info;
    }

    //计算优惠券
    function calc_coupon($user_id)
    {
        $cd = [
            'type' => 1,
        ];

        $coupon_list = (new CouponModel())->query_my_list($user_id, $cd, 0, 1);

        $coupon_info = null;

        $fee_info = [
            'coupon_fee' =>0,
            'coupon_metadata' => null,
            'coupon_id' => null,
        ];

        if (!empty($coupon_list)) {
            $coupon_info = $coupon_list[0];
            $couopon_amount = (new CouponModel())->coupon_amount($coupon_info);
            $fee_info['coupon_id'] = $coupon_info['id'];
            $fee_info['coupon_metadata'] = $coupon_info['metadata'];
            $fee_info['coupon_fee'] = $couopon_amount;
        }
        return $fee_info;
    }

    function adjust_amount($city_id, $id, $amount_type, $amount, $reason, $remark)
    {
        $lock = new DLock($id, 60);

        $order_info = $this->query_info_by_city_id($city_id, $id,false,true);
        if (empty($order_info)) {
            return [ERROR_QUERY_INFO, "查询订单失败!"];
        }

        if ($order_info['order_state'] != RIDE_ORDER_STATE_FINISH) {
            return [ERROR_STATE_DISMATCH, "订单未结束!"];
        }

        if (time() - strtotime($order_info['create_time']) > 3600 * 24 * 30) {
            //return [X_ERROR, "超过7天，不能调账!"];
        }

        if($order_info['is_pay'] == 0){
            return [X_ERROR, "订单未支付"];
        }

        if($amount < $order_info['paid_amount'])
        {
            $total = $order_info['paid_amount'] - $amount;
            if($total >0){
                $balance_fee = 0;
                $pay_fee =0;

                //先退余额
                $fee_info = $order_info['fee_info'];
                if(isset($fee_info['balance_fee'])&&isset($fee_info['pay_fee']))
                {
                    if ($fee_info['pay_fee'] >=$total)
                    {
                        $pay_fee = $total;
                    }
                    else
                    {
                        $pay_fee = $fee_info['pay_fee'];
                        $total -= $fee_info['pay_fee'];
                        if ($total > $fee_info['balance_fee'])
                        {
                            $balance_fee = $fee_info['balance_fee'];
                        }
                        else
                        {
                            $balance_fee = $total;
                        }
                    }
                }
                else
                {
                    //全退余额
                    $balance_fee = $total;
                }

                if ($balance_fee + $pay_fee != ($order_info['paid_amount'] - $amount)){
                    return [X_ERROR, "订单异常，反馈给程序"];
                }

                if ($balance_fee >0){
                    (new UserModel())->incr_balance($order_info['user_id'], $balance_fee);
                    (new PayModel())->add_record($order_info['city_id'], $order_info['user_id'], ORDER_TYPE_USER_RIDE_ADJUST_AMOUNT, $order_info['id'], PAY_GATEWAY_WALLET, $balance_fee);
                }

                if ($pay_fee>0){
                    $cd = [
                        'ride_order_id' =>$order_info['id'],
                        'user_id' => $order_info['user_id'],
                        'order_state' => USER_CHARGERIDE_ORDER_STATE_FINISHED,
                        'refundable' => 1,
                    ];
                    $charge_ride_list = (new UserChargeRideOrderModel())->query_list($cd, 0, 1);
                    if (count($charge_ride_list) >0){
                        (new UserChargeRideOrderModel())->submit_refund($charge_ride_list[0]['id'], $pay_fee, "退还用户零钱余额");
                        (new PayModel())->add_record($order_info['city_id'], $order_info['user_id'], ORDER_TYPE_USER_RIDE_ADJUST_AMOUNT, $order_info['id'], $charge_ride_list[0]['gateway'], $pay_fee);
                    }
                }
            }

        }

        $data = [
            'adjusted_amount' => $amount,
            'paid_amount' => $amount,
        ];

        $where = [
            'city_id' => $order_info['city_id'],
            'id' => $id,
        ];

        //hisql::update('tb_user_ride_order', $data, $where);
        Db::table($this->table_name)->where($where)->update($data);

        (new StatModel())->user_ride_order_amount_incr($order_info['city_id'], $order_info['create_time'], $amount - $order_info['paid_amount'],$order_info['start_svca_id']);

        $info = [
            'amount_type' => $amount_type,
            'original_amount' => $order_info['paid_amount'],
            'adjusted_amount' => $amount,
            'reason' => $reason,
            'remark' => $remark,
            'order_id' => $order_info['id'],
            'bike_id' => $order_info['bike_id'],
            'bike_sn' => $order_info['bike_sn'],
            'city_id' => $order_info['city_id'],
        ];

        $info = (new UserRideOrderAdjustAmountModel())->add($info);

        $adjust_amount = $amount- $order_info['paid_amount'];

        (new StatNewModel())->user_rider_adjust($order_info['city_id'],$order_info['end_time'],$adjust_amount);

        return [0, 'OK'];
    }


    function append_track($city_id, $order_id, $item, $distance = -1, $distance_incr = -1)
    {
        if ($distance >= 0 && !empty($item)) {
            $st = "update tb_user_ride_order set track = " . hisql::json_append_array_s('track', $item)
                . ", distance={$distance}" .
                " where city_id = ? and id = ?";

            $beans = [$city_id, $order_id];
            hisql::db()->execute($st, $beans);
        } else if ($distance_incr >= 0 && !empty($item)) {
            $st = "update tb_user_ride_order set track = " . hisql::json_append_array_s('track', $item)
                . ", distance=distance+{$distance_incr}" .
                " where city_id = ? and id = ?";

            $beans = [$city_id, $order_id];
            hisql::db()->execute($st, $beans);
        } else if ($distance >= 0) {
            $st = "update tb_user_ride_order set   distance={$distance}" .
                " where city_id = ? and id = ?";

            $beans = [$city_id, $order_id];
            hisql::db()->execute($st, $beans);
        }
    }

    function set_grsproad_track($city_id, $order_id, $track)
    {

        $data = [
            'track_grasproad' => $track,
        ];
        $where = [
            'city_id' => $city_id,
            'id' => $order_id,
        ];
        //hisql::update('tb_user_ride_order', $data, $where);
        Db::table($this->table_name)->where($where)->update($data);
    }

    function query_list($city_id, $condition, $pos, $limit)
    {
        $limit = min(30, $limit);
        $selectlist = [
            'id' => 'string',
            'city_id' => 'string',
            'user_id' => 'string',
            'user_name' => 'string',
            'user_phone' => 'string',
            'bike_id' => 'string',
            'bike_sn' => 'string',
            'imei' => 'string',
            'order_state' => 'int',
            'start_time' => 'string',
            'start_coordinate' => 'array',
            'start_address' => 'string',
            'start_park_id' => 'string',
            'start_park_name' => 'string',
            'end_time' => 'string',
            'end_coordinate' => 'array',
            'end_address' => 'string',
            'end_park_id' => 'string',
            'end_park_name' => 'string',
            'end_svca_id' => 'string',
            //'track' => 'string',
//  'payment_info' => 'array',
            'payment_gateaway' => 'string',
            'distance' => 'int',
            'duration' => 'int',
            'adjusted_amount' => 'int',
            'original_amount' => 'int',
            'paid_amount' => 'int',
            'is_flush' => 'int',
            'create_time' => 'string',
            'channel' => 'string',
            'is_violational' => 'int',
            'is_pay' => 'int',
            'user_repark_order' =>  'string',
            'user_repark_order_state' => 'int',
        ];
        $sfs = common::array_keys($selectlist);
        $st = "1 = 1 ";
        $beans = [
        ];
        if ($city_id !== null) {
            $st = $st . " and city_id = ?";
            $beans[] = $city_id;
        }
        if (isset($condition['order_state'])) {
            $st = $st . " and order_state = ?";
            $beans[] = $condition['order_state'];
        }
        if (isset($condition['is_start_from_park'])) {
            if ($condition['is_start_from_park']) {
                $st = $st . " and start_park_id is not null";
            } else {
                $st = $st . " and start_park_id is null";
            }
        }
        if (isset($condition['start_park_state'])) {
            $st = $st . " and start_park_state = ?";
            $beans[] = $condition['start_park_state'];
        }

        if (isset($condition['is_amount_adjusted'])) {
            if ($condition['is_amount_adjusted']) {
                $st = $st . " and original_amount <> adjusted_amount";
            } else {
                $st = $st . " and original_amount = adjusted_amount";
            }
        }
        if (isset($condition['is_flush'])) {
            $st = $st . " and is_flush = ?";
            $beans[] = $condition['is_flush'];
        }
        if (isset($condition['user_id'])) {
            $st = $st . " and user_id = ?";
            $beans[] = $condition['user_id'];
        }
        if (isset($condition['is_order_finished'])) {
            if ($condition['is_order_finished']) {
                $st = $st . " and order_state >= ?";
                $beans[] = RIDE_ORDER_STATE_FINISH;
            } else {
                $st = $st . " and order_state < ?";
                $beans[] = RIDE_ORDER_STATE_FINISH;
            }
        }
        if (isset($condition['start_time'])) {
            if(!empty($city_id)){
                $st = $st . " and id >= ?";
                $beans[] = $city_id . date('ymdHis', strtotime($condition['start_time']));
            }else{
                $st = $st . " and create_time >= ? ";
                $beans[] = $condition['start_time'];
            }
        }
        if (isset($condition['end_time'])) {
            if(!empty($city_id)){
                $st = $st . " and id <= ?";
                $beans[] = $city_id . date('ymdHis', strtotime($condition['end_time']));
            }else{
                $st = $st . " and create_time <= ? ";
                $beans[] = $condition['end_time'];
            }
        }
        if (isset($condition['bike_id'])) {
            $st = $st . " and bike_id = ?";
            $beans[] = $condition['bike_id'];
        }

        if (isset($condition['sk']) && !empty($condition['sk'])) {
            $sk = $condition['sk'];
            if (common::is_phone($sk)) {
                $st = $st . " and user_phone = ?";
                $beans[] = $sk;
            } else if (common::is_name($sk)) {
                $st = $st . " and user_name = ?";
                $beans[] = $sk;
            } else if (IDMan::is_bike_id($sk)) {
                $st = $st . " and bike_id = ?";
                $beans[] = $sk;
            } else if (IDMan::is_bike_sn($sk)) {
                $st = $st . " and bike_sn = ?";
                $beans[] = $sk;
            } else if (IDMan::is_city_order_id($sk)) {
                $st = $st . " and id = ?";
                $beans[] = $sk;
            } else if (IDMan::is_user_id($sk)) {
                $st = $st . " and user_id = ?";
                $beans[] = $sk;
            } else {
                return [];
            }
        }

        //$st = $st . " order by create_time desc limit $pos, $limit";
//
//        hilog::debug($st, $beans);
//        $result = hisql::db()->query($st, $beans);
        $rows =Db::table($this->table_name)->where($st,$beans)->field($sfs)->order('create_time','desc')->limit($pos,$limit)->select();

        return $rows->toArray();
    }

    function query_count()
    {
        return 100;
    }

    function query_my_list($user_id, $condition, $pno, $psize)
    {
        $selectlist = [
            'id' => 'string',
            'city_id' => 'string',
            'bike_id' => 'string',
            'order_state' => 'int',
            'start_time' => 'string',
            'start_coordinate' => 'array',
            'start_address' => 'string',
            'start_park_id' => 'string',
            'start_park_name' => 'string',
            'end_time' => 'string',
            'end_coordinate' => 'array',
            'end_address' => 'string',
            'end_park_id' => 'string',
            'end_park_name' => 'string',
            //'payment_info' => 'array',
            'payment_gateaway' => 'string',
            'distance' => 'int',
            'duration' => 'int',
            'adjusted_amount' => 'int',
            'original_amount' => 'int',
            'paid_amount' => 'int',
            'is_flush' => 'int',
            'create_time' => 'string',
            'is_violational' => 'int',
            'violation_fine' => 'int',
            'violation_blacklisted' => 'int',
        ];

        $sfs = common::array_keys($selectlist);
        $beans = [
            'user_id'=>$user_id,
        ];

        if (isset($condition['is_finished'])) {
            if (!$condition['is_finished']) {
                $beans['order_state'] = ['<',RIDE_ORDER_STATE_FINISH];
            } else {
                $beans['order_state'] = ['>=',RIDE_ORDER_STATE_FINISH];
            }
        }

        $pos = $condition['pos'];
        $limit = $condition['limit'];

        $rows =Db::table($this->table_name)->where($beans)->field($sfs)->order('create_time','desc')->limit($pos,$limit)->select();

        return $rows->toArray();
    }

    function query_track($city_id, $order_id)
    {
        $selectlist = [
            'bike_sn' => 'string',
            'start_time' => 'string',
            'end_time' => 'string',
            'start_coordinate' => 'array',
            'end_coordinate' => 'array',
            'start_park_state' => 'int',
            'end_park_state' => 'int',
            'track' => 'array',
        ];


        $sfs = common::array_keys($selectlist);
        $beans = [
            'city_id'=>$city_id,
            'id'=>$order_id,
        ];

        return Db::table($this->table_name)->where($beans)->field($sfs)->find();
    }

    function get_price_rule($city_id, $svca_id)
    {
        $price_rule = [];
        $score_rule = [];

        $svca_info = (new ServiceAreaModel())->info($city_id, $svca_id);
        if ($svca_info && !empty($svca_info['price_rule'])) {
            $price_rule = $svca_info['price_rule'];
        }

        if (empty($price_rule)) {
            $city_info = (new CityModel())->query_info($city_id);
            if ($city_info && !empty($city_info['price_rule'])) {
                $price_rule = $city_info['price_rule'];
            }
        }

        if (empty($score_rule)){
            $city_info = (new CityModel())->query_info($city_id);
            if ($city_info && !empty($city_info['score_rule'])) {
                $score_rule = $city_info['score_rule'];
            }
        }

        $score_fee_percent = 0;
        $score_basic_fee = 0;
        $use_score = 0;
        if (!empty($score_rule)){

            if (isset($score_rule['use_score'])){
                $use_score = $score_rule['use_score'];
            }

            if (isset($score_rule['fee_percent'])){
                $score_fee_percent = $score_rule['fee_percent'];
            }

            if (isset($score_rule['basic_fee'])){
                $score_basic_fee = $score_rule['basic_fee'];
            }
        }

        return array_merge(
            [
                'park_mode' => USER_ORDER_PARK_MODEL_FREE,
                "balance_mini" => 0,
                "basic_fee" => 300,
                "vip_basic_fee" => 200,
                "basic_kms" => 100,
                "basic_mins" => 30,
                "fee_per_min" => 10,
                "fee_min" => 1,
                "fee_per_km" => 0,
                'npa_fee' => 500,
                'osvc_fee' => 2000,
                'use_score' => $use_score,
                'score_basic_fee' => $score_basic_fee,
                'score_fee_per' => $score_fee_percent,
            ], $price_rule);
    }

    function set_violation_find_blacklist($city_id, $order_id, $fine, $blacklist)
    {
        //$st = "update tb_user_ride_order  set violation_fine = violation_fine + ?,  violation_blacklisted = violation_blacklisted + ? where city_id = ? and id = ?";
        $beans = [
            'city_id'=>$city_id,
            'id'=>$order_id];

        Db::table($this->table_name)->where($beans)->inc('violation_fine',$fine)->inc('violation_blacklisted',$blacklist)->update();
    }

    function set_violational($city_id, $order_id)
    {
        $data = [
            'is_violational' => 1,
        ];
        $where = [
            'city_id' => $city_id,
            'id' => $order_id,
        ];
        Db::table($this->table_name)->where($where)->update($data);
    }

    function  query_paying_list($city_id,$condition,$pos,$limit){
        $limit = min(30, $limit);
        $selectlist = [
            'id' => 'string',
            'city_id' => 'string',
            'user_id' => 'string',
            'order_state' => 'int',
            'payment_gateaway' => 'string',
            'distance' => 'int',
            'duration' => 'int',
            'fee_info' => 'object',
            'adjusted_amount' => 'int',
            'original_amount' => 'int',
            'paid_amount' => 'int',
            'is_flush' => 'int',
            'create_time' => 'string',
            'channel' => 'string',
            'is_violational' => 'int',
            'is_pay' => 'int',
        ];
        $sfs = common::array_keys($selectlist);
        $beans = [
        ];
        if ($city_id !== null) {
            $beans['city_id'] = $city_id;
        }
        if (isset($condition['order_state'])) {
            $beans['order_state'] = $condition['order_state'];
        }
        if (isset($condition['is_pay'])) {
            $beans['is_pay'] = $condition['is_pay'];
        }
        if (isset($condition['user_id'])) {
            $beans['user_id'] = $condition['user_id'];
        }
        if (isset($condition['is_order_finished'])) {
            if ($condition['is_order_finished']) {
                $beans['order_state'] = ['>=',RIDE_ORDER_STATE_FINISH];
            } else {
                $beans['order_state'] = ['<',RIDE_ORDER_STATE_FINISH];
            }
        }


        $rows = Db::table($this->table_name)->where($beans)->field($sfs)->order('create_time','desc')->limit($pos,$limit)->select();

        return $rows->toArray();
    }


    function modify_price($city_id, $id, $fee_info, $reason)
    {
        $lock = new DLock($id, 60);

        $order_info = $this->query_info_with_adjust_amount_record($city_id, $id);
        if (empty($order_info)) {
            return [ERROR_QUERY_INFO, "查询订单失败!"];
        }

        if ($order_info['order_state'] != RIDE_ORDER_STATE_FINISH) {
            return [ERROR_STATE_DISMATCH, "订单未结束!"];
        }

        if (time() - strtotime($order_info['create_time']) > 3600 * 24 * 7) {
            //return [X_ERROR, "超过7天，不能修改价格!"];
        }

        if($order_info['is_pay'] == 1){
            return [X_ERROR, "订单已支付,不能修改价格"];
        }

        $newfee = $order_info['fee_info'];
        $is_vip = 0;

        $base_fee = $newfee['no_coupon_fee'] -$newfee['mile_fee'] - $newfee['duration_fee'];
        if ($base_fee == $newfee['vip_basic_fee']){
            $is_vip = 1;
        }

        if ($is_vip == 1){
            $newfee['vip_basic_fee'] = $fee_info['basic_fee'];
        }else{
            $newfee['basic_fee'] = $fee_info['basic_fee'];
        }

        $newfee['mile_fee'] =  $fee_info['mile_fee'];
        $newfee['duration_fee'] =  $fee_info['duration_fee'];
        $newfee['npa_fee'] =  $fee_info['npa_fee'];
        $newfee['osvc_fee'] =  $fee_info['osvc_fee'];

        $newfee['total'] = $fee_info['basic_fee'] + $fee_info['mile_fee'] + $fee_info['duration_fee'];

        $newfee['no_coupon_fee'] = $newfee['total'];
        $newfee['total'] += $newfee['npa_fee'];
        $newfee['total'] += $newfee['osvc_fee'];

        $data = [
            'adjusted_amount' => $newfee['total'],
            'paid_amount' => $newfee['total'],
            'fee_info' => $newfee,
        ];

        $where = [
            'id' => $id,
        ];

        //hisql::update('tb_user_ride_order', $data, $where);
        Db::table($this->table_name)->where($where)->update($data);
        $info = [
            'amount_type' => 0,
            'original_amount' => $order_info['paid_amount'],
            'adjusted_amount' => $newfee['total'],
            'reason' => $reason,
            'remark' => $reason,
            'order_id' => $order_info['id'],
            'bike_id' => $order_info['bike_id'],
            'bike_sn' => $order_info['bike_sn'],
            'city_id' => $order_info['city_id'],
            'origin_text' => $order_info['fee_info'],
            'adjusted_text'=> $newfee,
        ];

        $info = (new UserRideOrderAdjustAmountModel())->add($info);

        //添加日志
        (new StatModel())->user_ride_order_amount_incr($order_info['city_id'], $order_info['create_time'], $newfee['total'] - $order_info['paid_amount'],$order_info['start_svca_id']);

        $adjust_amount = $newfee['total'] - $order_info['paid_amount'];

        (new StatNewModel())->user_rider_adjust($order_info['city_id'],$order_info['end_time'],$adjust_amount);

        return [0, 'OK'];
    }


    function hourly($city_id, $date) {
//substring(create_time, 9, 2) as day,
        $table = 'tb_user_ride_order';
        $st = "select substring(create_time, 12, 2) as hour, count(1) as cnt from $table where city_id = ? and create_time >= ? and create_time <= ? group by hour";
        $beans = [
            $city_id,
            $date . " 00:00:00",
            $date . " 23:59:59",
        ];
        $result = hisql::db()->query($st, $beans);
        $rows = $result->fetchAll(Phalcon\Db::FETCH_ASSOC);
        $l = [];
        foreach ($rows as $row) {
            $l[$row['hour']] = intval($row['cnt']);
        }
        return $l;
    }

    function hourly_all_city($date) {
//substring(create_time, 9, 2) as day,
        $beans = [];
        $table = 'tb_user_ride_order';
        $st = "select substring(create_time, 12, 2) as hour, count(1) as cnt from $table where 1=1 ";
        $cities = (new CityModel())->query_all(0,100);
        $city_ids = [];
        foreach ($cities as $city) {
            $city_ids[] = $city['id'];
        }

        hisql::bound_arg('city_id', $city_ids, $st, $beans, 'in');

        $st = $st . " and create_time >= ? and create_time <= ? group by hour";
        $beans[] = $date . " 00:00:00";
        $beans[] = $date . " 23:59:59";

//hilog::debug('hourly', $st, $beans);

        $result = hisql::db()->query($st, $beans);
        $rows = $result->fetchAll(Phalcon\Db::FETCH_ASSOC);
        $l = [];
        foreach ($rows as $row) {
            $l[$row['hour']] = intval($row['cnt']);
        }
        return $l;
    }

    function start_park_stats($city_id, $start_date, $end_date) {
       // $st = 'select start_park_id, start_park_name, count(start_park_id) as cnt from tb_user_ride_order where city_id = ? and create_time >=? and  create_time <= ? and start_park_id is not null group by start_park_id order by cnt desc limit 0,10';
        $beans = [
            'city_id'=>$city_id,
            'create_time'=>[['>=',$start_date . " 00:00:00"],['<=',$end_date . " 23:59:59"],'and'],
            'start_park_id'=>'not null'
        ];

       // $result = hisql::db()->query($st, $beans);
        $rows = Db::table($this->table_name)->where($beans)->field('start_park_id, start_park_name, count(start_park_id) as cnt')->group('cnt')->limit(10)->select();
        $l = [];
        foreach ($rows as $row) {
            $l[] = [
                'park_name' => $row['start_park_name'],
                'order_count' => intval($row['cnt']),
            ];
        }
        return $l;
    }
}

class UserRideOrderAdjustAmountModel
{
    protected $table_name = 'tb_user_ride_order_adjust_amount';

    function add($info)
    {
        $data = [
            'amount_type' => $info['amount_type'],
            'original_amount' => $info['original_amount'],
            'adjusted_amount' => $info['adjusted_amount'],
            'reason' => $info['reason'],
            'remark' => $info['remark'],
            'order_id' => $info['order_id'],
            'bike_id' => $info['bike_id'],
            'bike_sn' => $info['bike_sn'],
            'city_id' => $info['city_id'],
            'create_time' => date('Y-m-d H:i:s'),
            'id' => IDMan::city_order_id($info['city_id']),
        ];

        if (isset($info['origin_text'])){
            $data['original_text'] = $info['origin_text'];
        }

        if (isset($info['adjusted_text'])){
            $data['adjusted_text'] = $info['adjusted_text'];
        }

        $userinfo = ApiOper::instance()->userinfo();
        $data['user_name'] = $userinfo['name'];
        $data['user_id'] = $userinfo['id'];
        $data['user_phone'] = $userinfo['phone'];

        Db::table($this->table_name)->insert($data);
        //hisql::insert('tb_user_ride_order_adjust_amount', $data);
        return $data;
    }

    function query_list($city_id, $order_id)
    {
        $selectlist = [
            'amount_type' => 'int',
            'adjusted_amount' => 'int',
            'original_amount' => 'int',
            'reason' => 'string',
            'remark' => 'string',
            'user_name' => 'string',
            'create_time' => 'string',
        ];

        $sfs = common::array_keys($selectlist);
       // $st = "select SQL_CALC_FOUND_ROWS $sfs  from tb_user_ride_order_adjust_amount where city_id = ? and order_id = ? order by create_time desc";
        $beans = [
            'city_id'=>$city_id,
            'order_id'=>$order_id
        ];
        $rows = Db::table($this->table_name)->where($beans)->field($sfs)->order('create_time','desc')->select();
        $l = [];
        foreach ($rows as $row) {
            $l[] = common::sql_row($selectlist, $row);
        }
        return $l;
    }

}
